<?php
/**
 * CONTENIDO extension pack (mpContenidoX), consists of multiple classes to
 * provide more features for Plugins/Modules.
 *
 * @package     mpContenidoX
 * @subpackage  Factory
 * @author      Murat Purc <murat@purc.de>
 * @copyright   Copyright (c) 2008-2012 Murat Purc (http://www.purc.de)
 * @license     http://www.gnu.org/licenses/gpl-2.0.html - GNU General Public License, version 2
 * @version     $Id: mpContenido.class.php 21 2012-07-16 21:33:14Z purcaholic $
 */


defined('CON_FRAMEWORK') or die('Illegal call');


/**
 * CONTENIDO application class, works as a wrapper/singleton storage for common
 * used global variables.
 *
 * Stores singletons of global used instances such as Template, DB_Contenido,
 * Article cApiClient, cApiClientLanguage, CategoryItem, ...
 * The advantage is to provide once instance of application wide used objects.
 *
 * @package     mpContenidoX
 * @subpackage  Application
 * @author      Murat Purc <murat@purc.de>
 * @todo        Extend the features...
 */
final class mpContenido extends mpContenido_Core_Abstract
{

    /**
     * List of Language instances
     * @var  array
     */
    private static $_languages = array();

    /**
     * List of cApiClient instances
     * @var  array
     */
    private static $_clients = array();

    /**
     * List of cApiClientLanguage instances
     * @var  array
     */
    private static $_clientLanguages = array();

    /**
     * List of Article instances
     * @var  array
     */
    private static $_articles = array();

    /**
     * List of CategoryItem instances
     * @var  array
     */
    private static $_categories = array();

    /**
     * List of DB_Contenido instances
     * @var  array
     */
    private static $_databases = array();

    /**
     * Template instance
     * @var  Template
     */
    protected static $_template = null;


    /**
     * Returns instance of language object.
     *
     * @param   int  $idlang
     * @return  Language
     */
    public static function getLanguage($idlang=null)
    {
        $idclient = parent::getLanguageId($idlang);

        if (!isset(self::$_languages[$idlang])) {
            cInclude('classes', 'class.lang.php');
            self::$_languages[$idlang] = new Language($idlang);
        }
        return self::$_languages[$idlang];
    }


    /**
     * Returns instance of client object.
     *
     * @param   int  $idclient
     * @return  cApiClient
     */
    public static function getClient($idclient=null)
    {
        $idclient = parent::getClientId($idclient);

        if (!isset(self::$_clients[$idclient])) {
            cInclude('classes', 'class.client.php');
            self::$_clients[$idclient] = new cApiClient($idclient);
        }
        return self::$_clients[$idclient];
    }


    /**
     * Returns instance of cApiClientLanguage object.
     *
     * Stores created instance at first time and returns them by next call.
     * Is faster than create them each time.
     *
     * @param   int  $idclient  Id of client. If not set, the current client will be used.
     * @param   int  $idlang    Id of language. If not set, the current language will be used.
     * @return  cApiClientLanguage|null
     * @throws  Exception  If client id or language id is less than 1
     */
    public static function getClientLanguage($idclient=null, $idlang=null)
    {
        $idclient = parent::getClientId($idclient);
        $idlang   = parent::getLanguageId($idclient);
        $key      = $idclient . '_' . $idlang;

        if (!isset(self::$_clientLanguages[$key])) {
            cInclude('classes', 'contenido/class.clientslang.php');
            self::$_clientLanguages[$key] = new cApiClientLanguage(false, $idclient, $idlang);
        }
        return self::$_clientLanguages[$key];
    }


    /**
     * Returns instance of Article object.
     *
     * Stores created instance at first time and returns it by next call.
     * Is faster than create them each time.
     *
     * NOTE:
     * Don't use this function if you want to iterate through a huge amount of
     * articles, otherwhise you'll end up in exceeding allowed memory size.
     * This method is intended to retrieve instance of current available article.
     *
     * @param   int  $idart  Id of article. If not set, the current article id will be used.
     * @param   int  $idclient  Id of client. If not set, the current client will be used.
     * @param   int  $idlang    Id of language. If not set, the current language will be used.
     * @return  Article|null
     * @throws  Exception  If article id is less than 1
     */
    public static function getArticle($idart=0, $idclient=0, $idlang=0, $idartlang=0)
    {
        $idart = parent::getArticleId($idart);
        $idclient = parent::getClientId($idclient);
        $idlang = parent::getLanguageId($idlang);
        // @todo method to retrieve idartlang
        $idartlang = $idartlang;

        $key = $idart . '.' . $idlang;

        if (!isset(self::$_articles[$key])) {
            cInclude('classes', 'class.article.php');
            self::$_articles[$key] = new Article($idart, $idclient, $idlang, $idartlang);
        }
        return self::$_articles[$key];
    }


    /**
     * Returns instance of CategoryItem object.
     *
     * Stores created instance at first time and returns it by next call.
     * Is faster than create them each time.
     *
     * NOTE:
     * Don't use this function if you want to iterate through a huge amount of
     * categories, otherwhise you'll end up in exceeding allowed memory size.
     * This method is intended to retrieve instance of current available category.
     *
     * @param   int  $idcat  Id of category. If not set, the current category id will be used.
     * @return  CategoryItem|null
     * @throws  Exception  If category id is less than 1
     */
    public static function getCategory($idcat=null)
    {
        $idcat = parent::getCategoryId($idcat);

        if (!isset(self::$_categories[$idcat])) {
            cInclude('classes', 'class.category.php');
            self::$_categories[$idcat] = new CategoryItem($idcat);
        }
        return self::$_categories[$idcat];
    }

    // @todo implement this
    public static function getUser($iduser)
    {
    }


    /**
     * Returns the database object.
     *
     * Stores created instance at first time and returns it by next call.
     * Is faster than create them each time.
     *
     * @param   string  $host      Database host, uses configured value by default.
     * @param   string  $database  Database name, uses configured value by default.
     * @param   string  $user         Database user, uses configured value by default.
     * @param   string  $password  Database password, uses configured value by default.
     * @return  DB_Contenido
     */
    public static function getDatabase($host='', $database='', $user='', $password='')
    {
        $key = md5($host . $database . $user . $password);
        if (!isset(self::$_databases[$key])) {
            self::$_databases[$key] = new DB_Contenido($host, $database, $user, $password);
        }
        return self::$_databases[$key];
    }


    /**
     * Returns the template object.
     *
     * Stores created instance at first time and returns it by next call.
     * Is faster than create them each time.
     *
     * @return  Template
     */
    public static function getTemplate()
    {
        if (self::$_template == null) {
            self::$_template = new Template();
        }
        return self::$_template;
    }

}